import { ComponentClass } from 'react'
import Taro, { Component, Config } from '@tarojs/taro'
import { View, ScrollView } from '@tarojs/components'
import { connect } from '@tarojs/redux'

import HomeHeader from '../../components/home-header'
import HomeSwiper from '../../components/home-swiper'
import HomeLoan from '../../components/home-loan-box'
import HomeApply from '../../components/home-apply'
import HomeMorePorduct from '../../components/home-more-product'
import ProductFilterList from '../../components/product-filter-list'
import ProductFilter from '../../components/product-filter'
import ProductList from '../../components/product-list'

import { isTimeIntervalValid, getNextPage } from '../../utils/pagination'

// import InputOption from '../../model/product-list-input-option'
// import {
//   depositFilterOptions,
//   timeFilterOptions,
//   sortFilterOptions,
//   productTypeOptions,
//   mortgageTypeOptions,
//   jobsOptions
// } from '../../config';

import './index.scss'

// #region 书写注意
// 
// 目前 typescript 版本还无法在装饰器模式下将 Props 注入到 Taro.Component 中的 props 属性
// 需要显示声明 connect 的参数类型并通过 interface 的方式指定 Taro.Component 子类的 props
// 这样才能完成类型检查和 IDE 的自动提示
// 使用函数模式则无此限制
// ref: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/20796
//
// #endregion

type PageStateProps = {
  searchCondition: any
  searchOption: any,
  productPage: number,
  productList: any[],
  userApplyList: any[],
  effects: any,
  noneResultTips: string,
  noneResult: boolean,
  lastLoadTime: number,
  defaultPageSize: number,
}

type PageDispatchProps = {
  searchBank: (condition: any) => void,
}

type PageOwnProps = {}

type PageState = {
  // 页面Y轴滚动距离
  scrollTop: number
}

type IProps = PageStateProps & PageDispatchProps & PageOwnProps

interface Home {
  props: IProps;
  state: PageState;
}

@connect(({ home, common, loading }) => ({
  ...home,
  ...common,
  ...loading,
}), (dispatch) => ({
  searchBank(condition: any) {
    dispatch({
      type: 'home/searchBank',
      payload: condition
    })
  },
}))
class Home extends Component {

  constructor(props) {
    super(props);
    // this.state = {
    // searchOption: {
    //   deposit: depositFilterOptions[2],
    //   time_limit: timeFilterOptions[2],
    //   sort: sortFilterOptions[1],
    //   product_type: productTypeOptions[0],
    //   mortgage_type: mortgageTypeOptions[0],
    //   job: jobsOptions[0],
    // }
    // }
  }

  componentWillReceiveProps(nextProps) {

    // console.log('home page, componentWillReceiveProps this.props = ', this.props)
    // console.log('home page, componentWillReceiveProps nextProps = ', nextProps)
    const that = this
    // 搜索条件改变的情况下，重新加载产品
    const nextSearchCondition = nextProps.searchCondition
    const currSearchCondition = that.props.searchCondition
    if (nextSearchCondition && currSearchCondition
      && JSON.stringify(nextSearchCondition) !== JSON.stringify(currSearchCondition)) {
      // console.log('nextSearchCondition = ', nextSearchCondition)
      // console.log('currSearchCondition = ', currSearchCondition)
      // console.log('condition 有变化！！')

      // 要异步dispatch， 否则小程序会有问题...
      setTimeout(() => {
        that._reloadProduct(nextSearchCondition);
      }, 0)
    }
  }

  componentDidMount() {
    this._reloadProduct();
  }

  componentWillUnmount() { }

  componentDidShow() { }

  componentDidHide() { }

  render() {
    const { searchOption } = this.props
    // console.log('state.searchOption = ', this.state.searchOption)
    // console.log('searchOption = ', searchOption)

    return (
      <View className='home-container'>
        <ScrollView className='container'
          scrollY
          scrollWithAnimation
          scrollTop={0}
          lowerThreshold={0}
          style='height: 100vh'
          onScrollToLower={this.onLoadMoreProduct.bind(this)}
          onScroll={this.onViewScroll.bind(this)}>
          <HomeHeader />
          <View className='spanner-box'>
            <HomeSwiper />
          </View>
          <View className='loan-type-box'>
            <HomeLoan />
          </View>
          <View className='apply-box'>
            <HomeApply depositMoney={10000} />
          </View>
          <View className='more-product-box'>
            <HomeMorePorduct />
          </View>
          <View key='home-filter' className={ `product-filter-box` } id='#product-filter-box'>
            <ProductFilter inputOption={searchOption} dispatchActionType={'home/updateSearchCondition'} isNeedFixTop={true} scrollTop={this.state.scrollTop}/>
          </View>
          <View className='product-list-box'>
            <ProductList
              dataArray={this.props.productList}
              userApplyList={this.props.userApplyList}
              isShowCheck={false} isShowLoanTime={true} isShowApply={true} isShowCollectCancel={false}
              loading={this.props.effects['home/searchBank']}
              noneResult={this.props.noneResult}
              noneResultTips={this.props.noneResultTips} />
          </View>
        </ScrollView>

      </View>
    )
  }

  /**
   * 首页滚动到底部触发，加载更多
   * @param e 
   */
  onLoadMoreProduct(e) {
    if (this.props.effects['home/searchBank']) {
      console.log('加载数据中，return !!!', e)
      return
    } else {
      this._loadMoreProduct()
      console.log('滚动到底部，加载更多', e)
    }

  }

  /**
   * 页面滚动监视方法
   * @param e 
   * e 例子： event.detail = {scrollLeft, scrollTop, scrollHeight, scrollWidth, deltaX, deltaY}
   */
  onViewScroll(e) {
    // console.log('首页滚动, e = ', e.detail)
    // this._watchFilterComponentScroll(e.detail.scrollTop)
    // 更新 scrollTop
    this.setState({
      scrollTop: e.detail.scrollTop,
    })
  }

  /**
   * 初始化滚动参数
   */
  _initScrollParam() {

  }

  /**
   * 重新加载产品
   */
  _reloadProduct(condition?: any) {
    const { lastLoadTime } = this.props
    if (!isTimeIntervalValid(lastLoadTime)) {
      return
    }

    const searchCondition = condition || this.props.searchCondition
    this.props.searchBank({
      ...searchCondition,
      page: 1,
    })
  }

  /**
   * 加载更多产品
   * 加载下一页数据
   */
  _loadMoreProduct() {
    const { lastLoadTime } = this.props
    if (!isTimeIntervalValid(lastLoadTime)) {
      return
    }

    this.props.searchBank({
      ...this.props.searchCondition,
      page: getNextPage(this.props.productPage, this.props.defaultPageSize, this.props.productList.length),
    })
  }
}

// #region 导出注意
//
// 经过上面的声明后需要将导出的 Taro.Component 子类修改为子类本身的 props 属性
// 这样在使用这个子类时 Ts 才不会提示缺少 JSX 类型参数错误
//
// #endregion

export default Home as ComponentClass<PageOwnProps, PageState>
